package com.tinem.platform.module.validate;

import cn.hutool.core.util.ReflectUtil;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * 允许枚举值约束验证
 */
public class EnumAllowedValuesValidator implements ConstraintValidator<EnumAllowedValuesConstraint, Object> {

    private List<String> allowedValues;

    @Override
    public void initialize(EnumAllowedValuesConstraint constraintAnnotation) {
        allowedValues = Arrays.asList(constraintAnnotation.allowedValues());
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return true; // 允许为空值
        }
        if (value instanceof String) {
            return allowedValues.stream()
                    .anyMatch(v->v.equals(value));
        }
        if (value instanceof Integer) {
            return allowedValues.stream()
                    .map(Integer::parseInt)
                    .anyMatch(v->v.equals(value));
        }
        if (value instanceof Short) {
            return allowedValues.stream()
                    .map(Short::parseShort)
                    .anyMatch(v->v.equals(value));
        }
        if (value instanceof Byte) {
            return allowedValues.stream()
                    .map(Byte::parseByte)
                    .anyMatch(v->v.equals(value));
        }
        if (value instanceof Boolean) {
            return allowedValues.stream()
                    .map(Boolean::parseBoolean)
                    .anyMatch(v->v.equals(value));
        }
        if (value instanceof Float) {
            return allowedValues.stream()
                    .map(Float::parseFloat)
                    .anyMatch(v->v.compareTo((Float) value) == 0);
        }
        if (value instanceof Double) {
            return allowedValues.stream()
                    .map(Double::parseDouble)
                    .anyMatch(v->v.compareTo((Double) value) == 0);
        }
        if (value instanceof BigDecimal) {
            return allowedValues.stream()
                    .map(BigDecimal::new)
                    .anyMatch(v->v.compareTo((BigDecimal)value)==0);
        }

        if (value.getClass().isEnum()) {
            Method valueOf = ReflectUtil.getMethod(value.getClass(),"name");
            String name = ReflectUtil.invoke(value,valueOf);
            return allowedValues.stream()
                    .anyMatch(v->v.equals(name));
        }
        return false; // 值无效
    }
}
